package com.howso.cloud.common.crypto;

import cn.hutool.core.util.StrUtil;

/**
 * 加密综合对外api
 */
public class CrytoUtil {
    private static final String CRYTO_PRI = "cryto.pri.";
    private static final String CRYTO_PUB = "cryto.pub";
    private static final String DECRYPT_PREFIX = "cryto.decrypt.prefix";
    private static final String DECRYPT_SUFFIX = "cryto.decrypt.suffix";
    private static final String DATA_SPIT = "cryto.data.spit";
    private static final String PRIVATE_KEY;
    private static final String PUB_KEY;
    private static final String PREFIX_STRING;
    private static final String SUFFIX_STRING;
    private static final String SPIT_STRING;
    private static final String WORK_KEY_STRING;
    static {
        String[] privateKeys = new String[0];
        String temp="";
        int i=0;
        while (temp!=null){
            temp=SettingUtils.get(CRYTO_PRI+i);
            if(temp!=null){
                privateKeys=KeyCryptoUtil.insert(privateKeys,temp);
            }
            i++;
        }
        PRIVATE_KEY=KeyCryptoUtil.priKeyAssemble(privateKeys);
        PUB_KEY=SettingUtils.get(CRYTO_PUB);
        PREFIX_STRING=SettingUtils.get(DECRYPT_PREFIX);
        SUFFIX_STRING=SettingUtils.get(DECRYPT_SUFFIX);
        SPIT_STRING=SettingUtils.get(DATA_SPIT);
        WORK_KEY_STRING=KeyCryptoUtil.decrypt(KeyCryptoUtil.getWorkKeyCiphertext(),PRIVATE_KEY);
    }
    
    /**
     * 获取公钥
     * @return
     */
    public static String getPublicKey(){
        return PUB_KEY;
    }

    /**
     * 传输解密:接收到传输的数据包，先判断是否包含key，如果包含先进行私钥解密key，再解密data；如果不包含直接使用默认的工作密钥进行解密
     * @param data 传输密文 key--@@--data
     * @return
     */
    public static  String transferDecrypt(String data){
        String[] datas=data.split(SPIT_STRING);
        if(datas.length==1){
            return decrypt(KeyCryptoUtil.decrypt(data,PRIVATE_KEY),WORK_KEY_STRING);
        }else {
            return decrypt(KeyCryptoUtil.decrypt(datas[1],PRIVATE_KEY),KeyCryptoUtil.decrypt(datas[0],PRIVATE_KEY));
        }
        
    }
    /**
     * 传输加密：组装传输的加密数据； 不使用key，采用默认的工作key时，直接传输加密后的data数据，不进行处理。
     * @return data
     */
    public static String transferEncrypt(String data){
        //先用key进行加密，在用公钥进行加密
        return KeyCryptoUtil.encrypt(encrypt(data,WORK_KEY_STRING),getPublicKey());
    }
    
    /**
     * 组装传输的加密数据
     * @param data
     * @param key
     * @return
     */
    public static String transferEncrypt(String data,String key){
        String enKey=KeyCryptoUtil.encrypt(key,getPublicKey());
        return enKey+SPIT_STRING+KeyCryptoUtil.encrypt(encrypt(data,key),getPublicKey());
    }
    
    /**
     * 获取data加密用的key
     * @return
     */
    public static String getKey(){
        return DataCryptoUtil.generateAESKey();
    }
    
    /**
     * 获取data加密用的默认key workkey
     * @return
     */
    public static String getWorkKey(){
        return WORK_KEY_STRING;
    }

    /**
     * data 通用解密 判断前后缀是否包含，如果有则排除
     * @return
     */
    public static String decrypt(String data){
        if (data.startsWith(PREFIX_STRING)){
            if (StrUtil.isNotBlank(data)) {
                data = data.replace(PREFIX_STRING, "");
            } else {
                return data;
            }
        }
        if(data.contains(SUFFIX_STRING)){
            if(data.split(SUFFIX_STRING).length==1){
                return DataCryptoUtil.decrypt(data.replace(SUFFIX_STRING,""),WORK_KEY_STRING);
            }else {
                return DataCryptoUtil.decrypt(data.split(SUFFIX_STRING)[0],data.split(SUFFIX_STRING)[1]);
            }
        }else {
            return DataCryptoUtil.decrypt(data,WORK_KEY_STRING);
        }
        
    }
    
    /**
     * data解密
     * @param data 密文
     * @param hasPrefix 是否包含前缀，如果包含则先处理，同时判断后缀
     * @return
     */
    public static String decrypt(String data, boolean hasPrefix){
        if (hasPrefix || data.startsWith(PREFIX_STRING)){
            if (StrUtil.isNotBlank(data)) {
                data = data.replace(PREFIX_STRING, "");
            } else {
                return data;
            }
        }
        if(hasPrefix || data.contains(SUFFIX_STRING)){
            if(data.split(SUFFIX_STRING).length==1){
                return DataCryptoUtil.decrypt(data.replace(SUFFIX_STRING,""),WORK_KEY_STRING);
            }else {
                return DataCryptoUtil.decrypt(data.split(SUFFIX_STRING)[0],data.split(SUFFIX_STRING)[1]);
            }
        }else {
            return DataCryptoUtil.decrypt(data,WORK_KEY_STRING);
        }
    }
    
    /**
     * data解密
     * @param data 密文
     * @param keyStr key
     * @return
     */
    public static String decrypt(String data, String keyStr) {
        if ( data.startsWith(PREFIX_STRING)){
            if (StrUtil.isNotBlank(data)) {
                data = data.replace(PREFIX_STRING, "");
            } else {
                return data;
            }
        }
        if(data.contains(SUFFIX_STRING)){
            return DataCryptoUtil.decrypt(data.split(SUFFIX_STRING)[0],keyStr);
        }
        return DataCryptoUtil.decrypt(data,keyStr);
    }
    
    /**
     * data解密
     * @param data 密文
     * @param keyStr key
     * @param hasPrefix 是否包含前缀，如果包含则先处理
     * @return
     */
    public static String decrypt(String data, String keyStr, boolean hasPrefix) {
        if ( hasPrefix ||data.startsWith(PREFIX_STRING)){
            if (StrUtil.isNotBlank(data)) {
                data = data.replace(PREFIX_STRING, "");
            } else {
                return data;
            }
        }
        if(hasPrefix || data.contains(SUFFIX_STRING)){
            return DataCryptoUtil.decrypt(data.split(SUFFIX_STRING)[0],keyStr);
        }
        return DataCryptoUtil.decrypt(data,keyStr);
    }
    
    /**
     * data加密
     * @param data
     * @return
     */
    public static String encrypt(String data){
        return DataCryptoUtil.encrypt(data,WORK_KEY_STRING);
    }
    
    /**
     * data加密
     * @param data
     * @param hasPrefix 是否包含前缀 如果要包含。则加上前缀后缀，前缀申明加密参数，后缀带上密引
     * @return
     */
    public static String encrypt(String data, boolean hasPrefix){
        if(hasPrefix){
            return PREFIX_STRING+DataCryptoUtil.encrypt(data,WORK_KEY_STRING)+SUFFIX_STRING;
        }else {
            return DataCryptoUtil.encrypt(data,WORK_KEY_STRING);
        }
        
    }
    /**
     * data加密
     * @param data
     * @param keyStr
     * @return
     */
    public static String encrypt(String data, String keyStr) {
        return DataCryptoUtil.encrypt(data,keyStr);
    }
    
    /**
     * data加密
     * @param data
     * @param keyStr
     * @param hasPrefix 是否包含前缀 如果要包含。则加上前缀后缀，前缀申明加密参数，后缀带上密引
     * @return
     */
    public static String encrypt(String data, String keyStr, boolean hasPrefix) {
        if(hasPrefix){
            return PREFIX_STRING+DataCryptoUtil.encrypt(data,keyStr)+SUFFIX_STRING+keyStr;
        }else {
            return DataCryptoUtil.encrypt(data,keyStr);
        }
    }

}
